package asSkinStyle
{
	import asSkinStyle.data.StyleComposite;
	
	import flash.utils.describeType;

	/**
	 * UI工具类
	 * @author Pelephone
	 * @website http://cnblogs.com/pelephone
	 */
	internal class StyleUtils
	{
		/**
		 * 通过点语法路径返回组对象里的子对象。
		 * 如mc.info.txt_name表示的是cpe里面名为mc里面的info里面的txt_name对象
		 * @param cpe		要查找的显示容器
		 * @param pName		点语法名
		 		
		internal static function getCompositeByPointName(pName:String,cpe:Composite):Composite
		{
			if(pName.indexOf(UIMgr.SEPARATOR_CHILD)<0 && cpe.getChildByName(pName))
			{
				return cpe.getChildByName(pName);
			}
			else if(pName.indexOf(UIMgr.SEPARATOR_CHILD)>=0){
				var arr:Array = pName.split(UIMgr.SEPARATOR_CHILD);
				var c:Composite = cpe.getChildByName(pName);
				for each (var str:String in arr) 
				{
					var tc:Composite = c.getChildByName(str);
					if(!tc) return null;
					c = tc;
				}
				return c;
			}
			return null;
		}*/
		
		/**
		 * 通过点语法路径返回显示对象里的子对象。
		 * 如mc.info.txt_name表示的是cpe里面名为mc里面的info里面的txt_name对象
		 * @param cpe		要查找的显示容器
		 * @param pName		点语法名
		 
		internal static function getDispByPointName(pName:String,disp:DisplayObject):DisplayObject
		{
			if(pName.indexOf(UIMgr.SEPARATOR_CHILD)<0 && disp.name==pName)
			{
				return disp;
			}
			else if(pName.indexOf(UIMgr.SEPARATOR_CHILD)>=0){
				var arr:Array = pName.split(UIMgr.SEPARATOR_CHILD);
				var c:DisplayObject = disp;
				for each (var str:String in arr) 
				{
					if(!c is DisplayObjectContainer) continue;
					var tc:DisplayObject = (c as DisplayObjectContainer).getChildByName(str);
					if(!tc) return null;
					c = tc;
				}
				return c;
			}
			return null;
		}*/
		
		/**
		 * 通过空格语法获取项
		 * @param spName
		 * @return 
		 */
		internal static function getCssBySplitName(spName:String,cpe:StyleComposite):StyleComposite
		{
			if(spName.indexOf(ArrayToStyleParser.SEPARATOR_CHILD)<0)
			{
				return cpe.getChildByName(spName);
			}
			var arr:Array = spName.split(ArrayToStyleParser.SEPARATOR_CHILD);
			var cps:StyleComposite = cpe;
			for each (var str:String in arr) 
			{
				cps = cps.getChildByName(str);
				if(!cps) return null;
			}
			return cps;
		}
		
		/**
		 * 通过对象复制属性数据给resObj
		 * @param resObj
		 * @param newObj
		 * @param isStrict	是否严格，true时resObj有属性才赋值，false则会给resObj动态添属性
		 * @param ignoreProps	忽略的属性名列表
		 * @return 			返回改变属性后的原对象
		 */
		internal static function setObjByVars(resObj:Object,newObj:Object
											  ,isStrict:Boolean=true, ignoreProps:Array=null):Object
		{
			if(!newObj) return null;
			// 遍历样式对象属性改变dc的属性值
			for (var attName:String in newObj) 
			{
				var voVars:Object = newObj[attName] as Object;
				if(ignoreProps && ignoreProps.indexOf(attName)>=0) continue;
				if(isStrict && !resObj.hasOwnProperty(attName)) continue;
				resObj[attName] = voVars;
			}
			return resObj;
		}
		
		
		////////////////////////////////////////////////
		// xml解析部分
		///////////////////////////////////////////////
		
		/**
		 * 通过xml或xmlList节点对象生成动态对象
		 * @param xml
		 */
		internal static function xmlCreateObject(xml:Object):Object
		{
			if(xml) xml = xml[0];		// 调整到子结点
			if(xml==null || !XML(xml).length()) return null;
			var resObj:Object = {};
			for each (var child:Object in xml.attributes()) 
			{
				if(isNumber(child.toString()))
					resObj[child.localName()] = Number(child);
				else
					resObj[child.localName()] = child.toString();
			}
			return resObj;
		}
		
		/** 
		 * 是否是数值字符串;
		 */
		internal static function isNumber(char:String):Boolean
		{
			if (char == null)
			{
				return false;
			}
			return !isNaN(Number(char))
		}
		
		/**
		 * 将xml上的属性信息解析到单个对象
		 * @param xml			要解析的xml
		 * @param obj	  		要将xml解析到对象类
		 * @param ignoreProps	忽略的属性名列表
		 * @return 
		 */		
		static public function parseXMLItem(xml:Object, obj:Object, ignoreProps:Array=null):*
		{
			if(xml) xml = xml[0];		// 调整到子结点
			if(xml==null || !XML(xml).length()) return;
			
			var desc:XMLList = describeType( obj )["variable"];
			// 设置 obj 的每个属性 prop
			for each(var prop:XML in desc)
			{
				var propName:String = prop.@name;			// 变量名
				var propType:String = prop.@type;			// 变量类型
				
				// 忽略了
				if(ignoreProps && ignoreProps.indexOf(propName)>=0) continue;
				
				var list:XMLList = xml.attribute(propName);
				// 先判断是否有此属性,没有再判断是否有些节点
				if(!list.length()) list = xml.child(propName);
				// 如果无节点或者节点是数组则不解析
				if(!list.length() || list.length()>1) continue;
				
				switch(propType)
				{
					// 基本类型
					case "Boolean":
						obj[propName] = Boolean(int(list))
						break;
					case "int":
					case "uint":
					case "String":
					case "Number":
					{
						obj[propName] = list;		// 变量名 和 xml节点名 必须相同 
					}
						break;
				}
			}
			return obj;
		}
		
		/**
		 * 解析xml并生成新的对象返回
		 * @param xml		  要解析的xml
		 * @param tClass	  要将xml解析生成的类
		 * @param ignoreProps 忽略的属性名列表
		 * @return 
		 */		
		static public function parseXMLByClass(xml:Object, tClass:Class, ignoreProps:Array=null):*
		{
			if(xml) xml = xml[0];		// 调整到子结点
			if(xml==null || !XML(xml).length()) return;
			var obj:Object = new (tClass)();
			parseXMLItem(xml,obj,ignoreProps);
			return obj;
		}
		
		/**
		 * 将xml解析到数组对象里面,不包括子节点
		 * @param xmlList
		 * @param defaultClass
		 * @param ignoreProps
		 * @return 
		 */		
		static public function parseXMLList(xmlList:XMLList, defaultClass:Class, ignoreProps:Array=null):Array
		{
			if(xmlList==null || defaultClass==null) return null;
			var arr:Array = new Array;
			for each(var xml:XML in xmlList)
			{
				var obj:Object = parseXMLByClass(xml, defaultClass, ignoreProps);
				arr.push( obj ); 
			}
			return arr;
		}
		
		/**
		 * 通过xml数据创建皮肤组合
		 * @param skinXML
		 * @param idName
		 * @param tagName
		 * @param skinClass
		 * @return 
		 
		public static function createSkinCompositeByXML(skinXML:Object
							,idName:String="root",tagName:String=null,skinClass:Vector.<String>=null):SkinComposite
		{
			var scom:SkinComposite = new SkinComposite(idName,tagName,skinClass);
			for each (var childXML:Object in skinXML.children()) 
			{
				var tag:String = childXML.localName();
				var id:String = childXML.attribute("id");
				var clzStr:String = childXML.attribute("class");
				if(clzStr && clzStr.length>0)
					var clzArr:Array = String(childXML.attribute("class")).split(",");
				var skinClz:Vector.<String> = clzArr?Vector.<String>(clzArr):null;
				
				var childCom:SkinComposite = createSkinCompositeByXML(childXML,id,tag,skinClass);
				scom.add(childCom);
			}
			return scom;
		}*/
		
		/**
		 * 通过样式组合设置皮肤
		 * @param skin
		 * @param uiComposite
		 
		public static function setSkinUI(skin:DisplayObject,uiComposite:CssComposite):void
		{
//			setObjByVars(skin,uiComposite.getStyleVars());
//			var skinDC:DisplayObjectContainer = skin as DisplayObjectContainer;
//			if(!skinDC) return;
//			for (var i:int = 0; i < skinDC.numChildren; i++) 
//			{
//				
//			}
//			
//			for each (var disp:DisplayObjectContainer in skinDC.g) 
//			{
//				if(!disp) continue;
//				
//			}
			
		}*/
	}
}